﻿using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.Mvvm.Messaging;
using HsServerHa.Core;
using HsServerHa.Entity;
using HsServerHa.Entity.Models;
using HsServerHa.Entity.Models.SqlserverMirror;
using HsServerHa.Utility.SQLite;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Configuration;
using HsServerHa.Core.Http;
using HsServerHa.Utility.HttpHelper;

namespace HsServerHa.Utility.SqlserverMirror
{
    public class AddMirrorCommand : OperateCommandBase
    {
        public AddMirrorCommand()
        {
            Operate = "添加镜像";
            OperateCommand = OperateCommand.Begin;
        }

        public static void Add(string message)
        {
            WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>(message), "AddLog");
        }
        /// <summary>
        /// 加载动画
        /// </summary>
        /// <param name="value">True开启、Flase关闭</param>
        public static void Loading(bool value)
        {
            WeakReferenceMessenger.Default.Send(new ValueChangedMessage<bool>(value), "Loading");
        }
        /// <summary>
        /// 操作
        /// </summary>
        /// <returns></returns>
        public override async Task<OperateCommand> operate(ObservableCollection<string> LogTextBox, string path, bool isAutoCopy = true)
        {
            await Task.Run(() =>
              {
                  AddMirrorCommand.Loading(true);
                  switch (OperateCommand)
                  {
                      case OperateCommand.Begin://备份主体
                          if (CheckStatementCommand.BackMainDb(LogTextBox, MainSqlConnectString, DataBaseName, path, SlaveServer,isAutoCopy))
                          {
                              OperateCommand = OperateCommand.WaitCopyBackUp;
                              AddMirrorCommand.Loading(false);
                              if(isAutoCopy)
                                throw new Exception($"备份文件【{DataBaseName}】已成功复制到镜像服务器");
                              else
                                  throw new Exception($"请将数据库【{DataBaseName}】的备份文件复制到镜像服务器");
                          }
                          else
                          {
                              OperateCommand = OperateCommand.Begin;
                              AddMirrorCommand.Loading(false);
                              throw new Exception($"备份主体数据库【{DataBaseName}】失败！请重试");
                          }
                          break;
                      case OperateCommand.WaitCopyBackUp: //还原数据库镜像
                          if (!CheckStatementCommand.Restore(LogTextBox, SlaveSqlConnectString, DataBaseName, path))
                          {
                              OperateCommand = OperateCommand.WaitCopyBackUp;
                              AddMirrorCommand.Loading(false);
                              throw new Exception($"还原数据库【{DataBaseName}】失败！请重试");
                          }
                          else
                          {
                              OperateCommand = OperateCommand.WaitSetSlaverPartner;
                          }
                          break;
                      case OperateCommand.WaitSetSlaverPartner: //先在镜像数据库建立伙伴关系
                          if (!CheckStatementCommand.SetPartner(LogTextBox, SlaveSqlConnectString, DataBaseName, MainServer))
                          {
                              OperateCommand = OperateCommand.WaitSetSlaverPartner;
                              AddMirrorCommand.Loading(false);
                              throw new Exception("设置镜像服务器伙伴关系失败，请重试");
                          }
                          else
                          {
                              OperateCommand = OperateCommand.WaitSetMainPartner;
                          }
                          break;
                      case OperateCommand.WaitSetMainPartner:  //再在主体数据库建立伙伴关系
                          if (!CheckStatementCommand.SetPartner(LogTextBox, MainSqlConnectString, DataBaseName, SlaveServer))
                          {
                              OperateCommand = OperateCommand.WaitSetMainPartner;
                              AddMirrorCommand.Loading(false);
                              throw new Exception("设置主服务器伙伴关系失败，请重试");
                          }
                          else
                          {
                              OperateCommand = OperateCommand.Compelete;
                              InsertDataToSqlite(SlaveServer);
                          }
                          break;
                  }
              });
            AddMirrorCommand.Loading(false);
            return OperateCommand;
        }

        public bool InsertDataToSqlite(string slaveServer)
        {
            var parms = new SQLManageEntity
            {
                ProgramKey = GeneratePrimaryKeyIdHelper.GetPrimaryKeyId().ToString(),
                DBName = DataBaseName,
                Port = MainPort,
                UserId = UserName,
                UserPwd = Password,
                IsEnable = "是",
                CreateTime = DateTime.Now.ToString()
            };
            SQLiteHelper.ExecuteSql($"insert into SQLManage (ProgramKey,DBName,Port,UserId,UserPwd,IsEnable,CreateTime)" +
                                    $" values('{parms.ProgramKey}','{parms.DBName}','{parms.Port}','{parms.UserId}','{parms.UserPwd}','{parms.IsEnable}','{DateTime.Now.ToString()}')");

            #region 新增远程镜像数据                      
            var slavePath = $"http://{slaveServer}:{ConfigurationManager.AppSettings["HttpPort"]?.ToString() ?? "6601"}/";
            var result = HttpHelpers.PostToJson<HttpResponseResultModel<object>>(slavePath +
           (ConfigurationManager.AppSettings["postSqlManageAdd"]?.ToString() ?? "postSqlManageAdd"), JsonConvert.SerializeObject(parms)).Result;
            #endregion

            LoggerHelper.SetInfo("新增了数据库镜像:" + JsonConvert.SerializeObject(parms), "数据库镜像管理");
            WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>("刷新数据库数据"), "RefreshSQLManage");
            return true;
        }
    }
}
